﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "ActionDrawStructureVerticalColumn.h"
#include "AddStructureDynamicPannelUtil.h"
#include "IStructureVerticalColumn.h"
#include "StructureColumnInput.h"
#include "StructureFamilyUtils.h"
#include "StructureInstanceCmdUtils.h"
#include "StructureInstancePresetParameterUtils.h"
// 平台头文件
#include "GbmpBuiltInParameterDefinitionsNew.h"
#include "GbmpControlIds.h"
#include "GbmpGraphicsNodeUtils.h"
#include "GbmpJoinUtils.h"
#include "GbmpModelViewUtil.h"
#include "GbmpPresetParameterUIUtils.h"
#include "GcmpBuiltInCategoryUniIdentities.h"
#include "GcmpBuiltInParameterDefinitions.h"
#include "GraphicsNodeUtils.h"
#include "IActionInputDialog.h"
#include "IActionInputEvent.h"
#include "IActionInputEventArgs.h"

#include "ICheckBoxGroupDefinition.h"
#include "IDocument.h"
#include "IElementModelShape.h"
#include "IFamily.h"
#include "IFamilyType.h"
#include "IGraphicsElementShape.h"
#include "IGraphicsLine.h"
#include "IGraphicsNodeGroup.h"
#include "IGraphicsStyleManager.h"
#include "IInstance.h"
#include "IMainWindow.h"
#include "IModelView.h"
#include "IParameter.h"
#include "IParameterDefinitionLibrary.h"
#include "IPickPointAction.h"
#include "IPropertyPanelEvent.h"
#include "IPropertyPanelEventArgs.h"
#include "IPropertyWidget.h"
#include "IRadioButtonGroupDefinition.h"
#include "ITemporaryDimensionContext.h"
#include "ITemporaryDimensionManager.h"
#include "IUiDocument.h"
#include "IUiView.h"
#include "IUserTransaction.h"
#include "PropertyWidgetUtils.h"
#include "StructureInstanceSectionShapeType.h"
#include "Vector2dUtils.h"
#include "GUiBaseInterfaceEnums.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;
namespace 
{   
    const static std::wstring s_AnchorPointGroup = GBMP_TR(L"锚点");
    const static std::wstring s_PositionLeftTop = GBMP_TR(L"左上");
    const static std::wstring s_PositionRightTop = GBMP_TR(L"右上");
    const static std::wstring s_PositionLeftButtom = GBMP_TR(L"左下");
    const static std::wstring s_PositionRightButtom = GBMP_TR(L"右下");
    const static std::wstring s_PositionCenter = GBMP_TR(L"中心");
    const static std::wstring s_DrawColumnPlaceRotateGroup = GBMP_TR(L"放置后旋转组");
    const static std::wstring s_DrawColumnPlaceRotate = GBMP_TR(L"放置后旋转");
}
ActionDrawStructureVerticalColumn::ActionDrawStructureVerticalColumn(const gcmp::UniIdentity &category, Int32 categorySecondKey, ElementId familyId, ElementId instanceTypeId)
    : m_isUserCancelled(false),
    m_category(category),
    m_categorySecondKey(categorySecondKey),
    m_familyId(familyId),
    m_instanceTypeId(instanceTypeId),
    m_pDoc(nullptr),
    m_pCurrentView(nullptr),
    m_pInputDialog(nullptr)
{
    m_bActionStarted = false;
    m_InstanceDirectionStatus = IDS_Not_Started;
    m_bIsRotated = false;
    m_anchorType = InstanceAnchorPointType::CenterAnchorPointType;
}

ActionDrawStructureVerticalColumn::~ActionDrawStructureVerticalColumn()
{
    CleanupTempGraphicsShape();
    // 取消订阅Action输入对话框消息
    if (m_pInputDialog && m_pInputDialog->GetInputEvent())
    {
        m_pInputDialog->GetInputEvent()->Delete(this);
    }
    m_pInputDialog = nullptr;

    // 取消订阅属性表消息
    {
        if (IPropertyWidget *pPropertyWidget = IPropertyWidget::GetPropertyWidget())
        {
            pPropertyWidget->GetInputEvent()->Delete(this);
        }
    }

    // 属性面板
    GbmpPresetParameterUIUtils::UpdatePropertyPanel(ElementId::InvalidID);
    GbmpPresetParameterUIUtils::EnablePropertyPanel(true);
}

void ActionDrawStructureVerticalColumn::InitAction(IUiView* pCurrentView)
{
    //缓存当前Modelview
    DBG_WARN_AND_RETURN_VOID_UNLESS(pCurrentView, L"invalid pCurrentView",L"GDMPLab",L"2024-03-30");
    m_pCurrentView = pCurrentView->GetModelView();
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pCurrentView, L"invalid m_pCurrentView",L"GDMPLab",L"2024-03-30");

    //缓存当前文档
    IUiDocument* pUiDoc = pCurrentView->GetUiDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDoc, L"invalid pUiDoc",L"GDMPLab",L"2024-03-30");
    m_pDoc = pUiDoc->GetDbDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc, L"invalid m_pDoc",L"GDMPLab",L"2024-03-30");

    //创建预设临时对象
    OwnerPtr<IUserTransaction> opTransaction = IUserTransaction::Create(m_pDoc, GBMP_TR(L"创建预设参数对象"), true);
    ElementId presetColumnId = CreateInstance(Vector3d::Zero, 0, false, false, ElementCreationOptions::Transient);
    opTransaction->Commit();

    this->SetPreSetElementId(presetColumnId);

    //预设参数
    OwnerPtr<IUserTransaction> ut = IUserTransaction::Create(m_pDoc, GBMP_TR(L"保存当前创建实例的族类型到预设参数"), true);
    bool bOk = StructureInstancePresetParameterUtils::SetPresetInstanceType(m_pDoc, m_category, m_categorySecondKey, m_instanceTypeId);
    DBG_WARN_AND_RETURN_VOID_UNLESS(bOk, L"SetPresetInstanceType失败",L"GDMPLab",L"2024-03-30");
    ut->Commit();
    UpdateValueInputPane();
    // 订阅输入框消息
    if (m_pInputDialog && m_pInputDialog->GetInputEvent())
    {
        m_pInputDialog->GetInputEvent()->Add(this);
    }
    // 订阅属性表消息
    if (IPropertyWidget *pPropertyWidget = IPropertyWidget::GetPropertyWidget())
    {
        pPropertyWidget->GetInputEvent()->Add(this);
    }
    AddStructureDynamicPannelUtil::SetupColumnCreationContext(this, ID_PAGE_GBMP_MODIFY);
    IMainWindow::GetMainWindow()->UpdateControlStatus();

    GbmpPresetParameterUIUtils::UpdatePropertyPanel(presetColumnId);
    GbmpPresetParameterUIUtils::EnablePropertyPanel(true);
        
    m_bActionStarted = true;
    GettingInstancePlacePoint();
}

void ActionDrawStructureVerticalColumn::OnChildActionFinished(IUiView* pCurrentView, const ActionOutput& childActionReturnParam)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(nullptr != pCurrentView, L"pCurrentView为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    if(m_isUserCancelled)
    {
        // 如果用户选择退出
        CleanupTempGraphicsShape();
        MarkFinishStatus(ActionFinishStatus::Successful);
        UpdateView();
        return;
    }

    if(m_bIsRotated)
    {
        if(IDS_Getting_PlacePoint == m_InstanceDirectionStatus)
        {
            GbmpPresetParameterUIUtils::EnablePropertyPanel(false);

            m_pickedPoints.clear();
            m_pickedPoints.push_back(m_placePt);
            m_pickedPoints.push_back(m_placePt + Vector3d::UnitX * 1000);
            GettingDirectionPoint();
        }
        else if (IDS_Getting_DirectionPoint == m_InstanceDirectionStatus)
        {
            GbmpPresetParameterUIUtils::EnablePropertyPanel(true);
            CleanupTempGraphicsShape();

            Vector3d dir = m_directionPt - m_placePt;
            dir.Normalize();
            Coordinate3d coord = GbmpModelViewUtil::GetWorkPlaneCoordinate(pCurrentView->GetModelView());
            double dAngle = Vector2dUtils::GetAngle(Vector2d(coord.GetX().GetX(), coord.GetX().GetY()), Vector2d(dir.X(), dir.Y()));

            OwnerPtr<IUserTransaction> ut = IUserTransaction::Create(m_pDoc, GBMP_TR(L"创建GBMP普通点式族实例"));

            ElementId instanceId = CreateInstance(m_placePt, dAngle, true, false);
            DBG_WARN_AND_RETURN_VOID_UNLESS(instanceId.IsValid(), L"instanceId无效",L"GDMPLab",L"2024-03-30");
            GbmpJoinUtils::CreateJoinsAndCuts(m_pDoc, instanceId);

            ut->Commit();

            UpdateView();

            GettingInstancePlacePoint();
        }
    }
    else
    {
        OwnerPtr<IUserTransaction> ut = IUserTransaction::Create(m_pDoc, GBMP_TR(L"创建GBMP普通点式族实例"));

        ElementId instanceId = CreateInstance(m_placePt, 0, true, false);
        DBG_WARN_AND_RETURN_VOID_UNLESS(instanceId.IsValid(), L"instanceId无效",L"GDMPLab",L"2024-03-30");
        GbmpJoinUtils::CreateJoinsAndCuts(m_pDoc, instanceId);

        ut->Commit();

        UpdateView();

        GettingInstancePlacePoint();
    }
}

bool ActionDrawStructureVerticalColumn::OnViewSwitched(IUiView* pUIView)
{
    MarkFinishStatus(ActionFinishStatus::Successful);
    return true;
}

void ActionDrawStructureVerticalColumn::GettingInstancePlacePoint()
{
    SetPromptMessage(GBMP_TR(L"请输入结构柱放置点"));

    m_InstanceDirectionStatus = IDS_Getting_PlacePoint;
    m_isUserCancelled = false;

    gcmp::OwnerPtr<IPickPointAction> upPickPointAction(IPickPointAction::Create( 
        PickPointExchangeData(&m_placePt, &m_isUserCancelled, &m_pickedPoints)
        , IPickPointAction::CreateMoveCallback(&ActionDrawStructureVerticalColumn::PreviewByPlacePoint, this)));
    StartChildAction(TransferOwnership(upPickPointAction));
}

void ActionDrawStructureVerticalColumn::GettingDirectionPoint()
{
    m_InstanceDirectionStatus = IDS_Getting_DirectionPoint;
    SetPromptMessage(GBMP_TR(L"请输入旋转结束线"));

    m_isUserCancelled = false;

    gcmp::OwnerPtr<IPickPointAction> upPickPointAction(IPickPointAction::Create( 
        PickPointExchangeData(&m_directionPt, &m_isUserCancelled, &m_pickedPoints)
        , IPickPointAction::CreateMoveCallback(&ActionDrawStructureVerticalColumn::PreviewByPlacePointWithDirection, this)));
    upPickPointAction->SetFirstPoint(m_placePt);
    StartChildAction(TransferOwnership(upPickPointAction));
}

void ActionDrawStructureVerticalColumn::UpdateValueInputPane()
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc, L"invalid m_pDoc！",L"GDMPLab",L"2024-03-30");

    const IFamily* pFamily = quick_cast<IFamily>(m_pDoc->GetElement(m_familyId));
    DBG_WARN_AND_RETURN_VOID_UNLESS(pFamily, L"无法获取Family",L"GDMPLab",L"2024-03-30");

    // 判断是否是圆柱，圆柱不需要 “放置后旋转” 选项
    bool bCircleColumn = false;
    //判断是否是自定义界面柱，自定义截面柱无需锚点选项
    bool bCustomizedProfileColumn = false;
    {
        std::wstring instanceTypeName = L"";
        StructureFamilyUtils::GetInstanceTypeNameByTypeId(m_pDoc, m_instanceTypeId, instanceTypeName);

        const IFamilyType* pFamilyType = ((const IFamily*)pFamily)->GetFamilyTypeByName(instanceTypeName);
        DBG_WARN_AND_RETURN_VOID_UNLESS(pFamilyType != nullptr, L"族类型为空",L"GDMPLab",L"2024-03-30");
        const std::vector<OwnerPtr<IParameter>> parameters = pFamilyType->GetFamilyParameters();
        for (int i = 0; i < (int)parameters.size(); i++)
        {
            if (PARAMETER_UID(CircSectionDiameterBuiltInParameter).HasSameValue(parameters[i]->GetParameterDefinitionUid()))
            {
                bCircleColumn = true;
                break;
            }
            if (PARAMETER_UID(SectionShapeBuiltInParameter).HasSameValue(parameters[i]->GetParameterDefinitionUid()))
            {
                if (parameters[i]->GetValueAsInt() == (int)StructureInstanceSectionShapeType::SECTION_SHAPE_CUSTOMIZED)
                {
                    bCustomizedProfileColumn = true;
                    break;
                }
            }
        }
    }
    //根据柱的类别 配置输入选项
    {
        if (bCircleColumn)// 圆形柱 没有输入框
        {
            // 圆形柱 无放置后旋转
            m_bIsRotated = false;

            // 圆形柱 锚点总是在中心
            m_anchorType = InstanceAnchorPointType::CenterAnchorPointType;
        }
        else //自定义截面柱和其他柱的
        {
            std::vector<OwnerPtr<IControlDefinition>> dlgInputCtrlDefines;
            if (bCustomizedProfileColumn)
            {
                // 添加 放置后旋转   
                OwnerPtr<ICheckBoxGroupDefinition> pCheckBoxGroupDefRotation = ICheckBoxGroupDefinition::Create(s_DrawColumnPlaceRotateGroup, s_DrawColumnPlaceRotateGroup);
                CheckState groupDefRotation = m_bIsRotated ? CheckState::Checked : CheckState::Unchecked;
                pCheckBoxGroupDefRotation->AddCheckBox(s_DrawColumnPlaceRotate, GBMP_TR(s_DrawColumnPlaceRotate), GBMP_TR(s_DrawColumnPlaceRotate), groupDefRotation);
                dlgInputCtrlDefines.push_back(TransferOwnership(pCheckBoxGroupDefRotation));
                m_pInputDialog = IActionInputDialog::Create(GBMP_TR(L"柱"), TransferOwnership(dlgInputCtrlDefines), this);
            }
            else
            {
                // 添加 锚点设置
                OwnerPtr<IRadioButtonGroupDefinition> opPosTypeGroupDef = IRadioButtonGroupDefinition::Create(s_AnchorPointGroup, s_AnchorPointGroup);
                opPosTypeGroupDef->AddRadioButton(s_PositionLeftTop, s_PositionLeftTop, s_PositionLeftTop);
                opPosTypeGroupDef->AddRadioButton(s_PositionRightTop, s_PositionRightTop, s_PositionRightTop);
                opPosTypeGroupDef->AddRadioButton(s_PositionLeftButtom, s_PositionLeftButtom, s_PositionLeftButtom);
                opPosTypeGroupDef->AddRadioButton(s_PositionRightButtom, s_PositionRightButtom, s_PositionRightButtom);
                opPosTypeGroupDef->AddRadioButton(s_PositionCenter, s_PositionCenter, s_PositionCenter);
                opPosTypeGroupDef->SetCurrentRadioButton(s_PositionCenter);
                dlgInputCtrlDefines.push_back(TransferOwnership(opPosTypeGroupDef));
                // 添加 放置后旋转
                OwnerPtr<ICheckBoxGroupDefinition> pCheckBoxGroupDefRotation = ICheckBoxGroupDefinition::Create(s_DrawColumnPlaceRotateGroup, s_DrawColumnPlaceRotateGroup);
                CheckState groupDefRotation = m_bIsRotated ? CheckState::Checked : CheckState::Unchecked;
                pCheckBoxGroupDefRotation->AddCheckBox(s_DrawColumnPlaceRotate, GBMP_TR(s_DrawColumnPlaceRotate), GBMP_TR(s_DrawColumnPlaceRotate), groupDefRotation);
                dlgInputCtrlDefines.push_back(TransferOwnership(pCheckBoxGroupDefRotation));
                m_pInputDialog = IActionInputDialog::Create(GBMP_TR(L"柱"), TransferOwnership(dlgInputCtrlDefines), this);
            }
        }
    }
}

OwnerPtr<StructureColumnInput> ActionDrawStructureVerticalColumn::GetInstanceInput()
{
    OwnerPtr<StructureColumnInput> columnInput = NEW_AS_OWNER_PTR(StructureColumnInput);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(columnInput, L"invalid columnInput",L"GDMPLab",L"2024-03-30");

    bool bOk = StructureInstanceCmdUtils::GenerateVerticalColumnInput(m_pDoc, m_pCurrentView,
        m_category, m_categorySecondKey, m_familyId, m_instanceTypeId, *columnInput);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(bOk, L"GenerateVerticalColumnInput失败",L"GDMPLab",L"2024-03-30");

    return TransferOwnership(columnInput);
}

ElementId ActionDrawStructureVerticalColumn::CreateInstance(const gcmp::Vector3d& point, double rotateAngle, bool isVisible
    , bool canBeShared, gcmp::ElementCreationOptions createOption)
{
    OwnerPtr<StructureColumnInput> opInput = GetInstanceInput();
    {
        opInput->PositionPoints = std::vector<Vector3d>{ point };
        opInput->RotateAngle = rotateAngle;
        opInput->CanBeShared = canBeShared;
        opInput->Visible = isVisible;
        opInput->CreationOption = createOption;
        opInput->IsVerticalColumn = true;
        opInput->AnchorType = m_anchorType;
    }

    IStructureVerticalColumn* pColumn = IStructureVerticalColumn::Create(opInput.get());
    DBG_WARN_AND_RETURN_UNLESS(pColumn,ElementId::InvalidID, L"创建柱失败",L"GDMPLab",L"2024-03-30");

    return pColumn->GetElementId();
}

void ActionDrawStructureVerticalColumn::PreviewByPlacePoint(IUiView* pCurrentView, const gcmp::Vector3d& pos, const gcmp::Vector3d& mousePt)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc, L"Document为空",L"GDMPLab",L"2024-03-30");

    OwnerPtr<IUserTransaction> ut = IUserTransaction::Create(m_pDoc, GBMP_TR(L"创建预览对象"));

    ElementId columnId = CreateInstance(pos, 0, true, false);
    DBG_WARN_AND_RETURN_VOID_UNLESS(columnId.IsValid(), L"columnId为空",L"GDMPLab",L"2024-03-30");

    IInstance *pColumn = quick_cast<IInstance>(m_pDoc->GetElement(columnId));
    DBG_WARN_AND_RETURN_VOID_UNLESS(pColumn, L"pColumn为空",L"GDMPLab",L"2024-03-30");

    OwnerPtr<IGraphicsElementShape> tempGrep = TransferOwnershipCast<IGraphicsElementShape>(pColumn->GetElementModelShape()->GetGraphicsElementShape()->Clone());
    DBG_WARN_AND_RETURN_VOID_UNLESS(tempGrep != nullptr, L"无效的tempGrep指针",L"GDMPLab",L"2024-03-30");
    OwnerPtr<IGraphicsNodeGroup> tempGpGrep = gcmp::GbmpGraphicsNodeUtils::TransferGRepToGGroup(TransferOwnership(tempGrep));

    if(nullptr != tempGpGrep)
    {
        tempGpGrep->SetIsSnappable(false);
        // 如果 IGraphicsElementShape 在事务中创建且事务被撤消了，那么 IGraphicsElementShape 上的样式或者材质的 ElementId 可能就引用到了一个被销毁的 Element 对象上（族文档中有样式或材质被映射到主文档）
        // 下面的代码是将 IGraphicsElementShape 上的样式和材质的 ElementId 全部清空，并将 IGraphicsElementShape 以“临时对象样式”进行渲染
        GraphicsNodeUtils::CleanGraphicsNodeStyleAndMaterial(m_pDoc, tempGpGrep.get());
        tempGpGrep->SetGraphicsStyleId(m_pDoc->GetGraphicsStyleManager()->GetGraphicsStyleIdByCategoryUid(BuiltInCategoryUniIdentities::BICU_TEMP_STYLE));

        DrawTempGraphicsNodeGroup(TransferOwnership(tempGpGrep));
    }

    ut->Rollback();
}

void ActionDrawStructureVerticalColumn::PreviewByPlacePointWithDirection(IUiView* pCurrentView, const gcmp::Vector3d& pos, const gcmp::Vector3d& mousePt)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(nullptr != pCurrentView, L"pCurrentView为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc, L"m_pDoc为空",L"GDMPLab",L"2024-03-30");

    //计算角度等数据
    Vector3d dir = pos - m_placePt;
    dir.Normalize();
    Coordinate3d coord = GbmpModelViewUtil::GetWorkPlaneCoordinate(pCurrentView->GetModelView());
    double dAngle = Vector2dUtils::GetAngle(Vector2d(coord.X().X(), coord.X().Y()), Vector2d(dir.X(), dir.Y()));

    OwnerPtr<IUserTransaction> ut = IUserTransaction::Create(m_pDoc, GBMP_TR(L"创建预览对象"));

    ElementId columnId = CreateInstance(m_placePt,dAngle, true, false);
    DBG_WARN_AND_RETURN_VOID_UNLESS(columnId.IsValid(), L"columnId为空",L"GDMPLab",L"2024-03-30");

    IInstance *pColumn = quick_cast<IInstance>(m_pDoc->GetElement(columnId));
    DBG_WARN_AND_RETURN_VOID_UNLESS(pColumn, L"pColumn为空",L"GDMPLab",L"2024-03-30");

    //3. 获得辅助非临时Instance的Grep
    OwnerPtr<IGraphicsElementShape> tempGrep = TransferOwnershipCast<IGraphicsElementShape>(pColumn->GetElementModelShape()->GetGraphicsElementShape()->Clone());
    DBG_WARN_AND_RETURN_VOID_UNLESS(tempGrep != nullptr, L"tempGrep指针无效",L"GDMPLab",L"2024-03-30");
    OwnerPtr<IGraphicsNodeGroup> tempGpGrep = gcmp::GbmpGraphicsNodeUtils::TransferGRepToGGroup(TransferOwnership(tempGrep));
    tempGpGrep->SetIsSnappable(false);

    ut->Rollback();

    //4. 两点之间连线
    tempGpGrep->AddChild(TransferOwnership(IGraphicsLine::Create(m_placePt, pos)));

    // 临时尺寸标注
    Vector3d angleStartPt = m_placePt + Vector3d::UnitX * 1000;
    OwnerPtr<ITemporaryDimensionContext> opCtx = ITemporaryDimensionContext::CreateRotationContext(
        m_placePt, angleStartPt, pos, GbmpModelViewUtil::GetWorkPlaneCoordinate(pCurrentView->GetModelView()));
    tempGpGrep->AddChild((ITemporaryDimensionManager::Get()->GenerateTemporaryDimensionGraphics(opCtx.get())));
    
    // 如果 IGraphicsElementShape 在事务中创建且事务被撤消了，那么 IGraphicsElementShape 上的样式或      者材质的 ElementId 可能就引用到了一个被销毁的 Element 对象上（族文档中有样式或材质被映射到主文档）
    // 下面的代码是将 IGraphicsElementShape 上的样式和材质的 ElementId 全部清空，并将 IGraphicsElementShape 以“临时对象样式”进行渲染
    GraphicsNodeUtils::CleanGraphicsNodeStyleAndMaterial(m_pDoc, tempGpGrep.get());
    tempGpGrep->SetGraphicsStyleId(m_pDoc->GetGraphicsStyleManager()->GetGraphicsStyleIdByCategoryUid(BuiltInCategoryUniIdentities::BICU_TEMP_STYLE));

    DrawTempGraphicsNodeGroup(TransferOwnership(tempGpGrep));
}

void ActionDrawStructureVerticalColumn::On(IActionInputEventArgs* pArgs)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pArgs, L"pArgs为空",L"GDMPLab",L"2024-03-30");
    const std::pair<std::wstring, gcmp::Any>& msg = pArgs->GetInputMessage();
    const std::wstring eventID = msg.first;
    gcmp::Any inputValue = msg.second;
    if (eventID == s_DrawColumnPlaceRotateGroup + L"_" + s_DrawColumnPlaceRotate)
    {
        m_bIsRotated = inputValue.cast<bool>();
    }
    else if (eventID == s_AnchorPointGroup)
    {
        std::wstring anchorType = inputValue.cast<std::wstring>();
        if (anchorType == s_PositionLeftTop)
            m_anchorType = InstanceAnchorPointType::LeftTopAnchorPointType;
        else if (anchorType == s_PositionRightTop)
            m_anchorType = InstanceAnchorPointType::RightTopAnchorPointType;
        else if (anchorType == s_PositionLeftButtom)
            m_anchorType = InstanceAnchorPointType::LeftBottomAnchorPointType;
        else if (anchorType == s_PositionRightButtom)
            m_anchorType = InstanceAnchorPointType::RightBottomAnchorPointType;
        else if (anchorType == s_PositionCenter)
            m_anchorType = InstanceAnchorPointType::CenterAnchorPointType;
        else
        {
            DBG_WARN(L"对话框的inputValue不在范围内",L"GDMPLab",L"2024-03-30");
            m_anchorType = InstanceAnchorPointType::CenterAnchorPointType;
        }

    }
}
void ActionDrawStructureVerticalColumn::On(gcmp::IPropertyPanelEventArgs* pArgs)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pArgs, L"pArgs为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pDoc, L"pDoc为空",L"GDMPLab",L"2024-03-30");

    // TODO: 接口
    if (PropertyWidgetUtils::IsComponentTypeChangedEvent(pArgs->GetPropertyItemUniqueId()))
    {
        ElementId newInstanceTypeId(StringUtil::ToNumber<Int64>(pArgs->GetNewValue()));
        DBG_WARN_AND_RETURN_VOID_UNLESS(newInstanceTypeId.IsValid(), L"newInstanceTypeId无效",L"GDMPLab",L"2024-03-30");

        ElementId newFamilyId;
        bool bOk = StructureFamilyUtils::GetFamilyIdByTypeId(m_pDoc, newInstanceTypeId, newFamilyId);
        DBG_WARN_AND_RETURN_VOID_UNLESS(bOk, L"GetFamilyNameByTypeId失败",L"GDMPLab",L"2024-03-30");

        if (m_familyId.HasSameValue(newFamilyId) && m_instanceTypeId.HasSameValue(newInstanceTypeId))
            return;

        //缓存，并设置预设参数
        m_familyId = newFamilyId;
        m_instanceTypeId = newInstanceTypeId;

        OwnerPtr<IUserTransaction> opTransaction = IUserTransaction::Create(m_pDoc, GBMP_TR(L"保存当前创建实例的族类型到预设参数"), true);
        bOk = StructureInstancePresetParameterUtils::SetPresetInstanceType(m_pDoc, m_category, m_categorySecondKey, newInstanceTypeId);
        DBG_WARN_AND_RETURN_VOID_UNLESS(bOk, L"SetPresetInstanceType失败",L"GDMPLab",L"2024-03-30");
        opTransaction->Commit();

        CleanupTempGraphicsShape();
    }


}
